﻿//------------------------------------------------------------------------------
//  Namespace: FruitVentDesign.Controls
//  
//  Function： N/A
//  Name： RoundProgressBar
//  
//  Ver       Time                     Author
//  0.10      2021/6/17 11:43:29      FruitVent
//
//  此代码版权归作者本人FruitVent所有
//  源代码使用协议遵循本仓库的开源协议及附加协议，若本仓库没有设置，则按MIT开源协议授权
//  CSDN博客：https://blog.csdn.net/weixin_39552347
//  源代码仓库：https://gitee.com/fruitvent
//  感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using FruitVentDesign.Utils;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace FruitVentDesign.Controls
{
    public class RoundProgressBar : ContentControl
    {
        static RoundProgressBar()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(RoundProgressBar), new FrameworkPropertyMetadata(typeof(RoundProgressBar)));
        }

        private static ResourceDictionary resourceDictionary = new ResourceDictionary();//资源字典
        private RotateTransform _rotateTransform = null;
        DoubleAnimation _rotateAnimation = new DoubleAnimation();
        private Storyboard _rotatedStory = new Storyboard();
        private Canvas canvas = null;

        public RoundProgressBar()
        {
            resourceDictionary.Source = new Uri(
                $"pack://application:,,,/FruitVentDesign;component/Skins/" +
                $"{Configurations.Cinfiguration.ThemeColor}.xaml");//获取资源字典

            IsVisibleChanged += RoundProgressBar_IsVisibleChanged;
        }

        private void RoundProgressBar_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (!IsVisible)
            {
                _rotatedStory.Stop(canvas);
                _rotatedStory.Remove();
            }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            canvas = Template.FindName("Canvas", this) as Canvas;
            InitCanvas();
        }

        /// <summary>
        /// initalize canvas
        /// </summary>
        private void InitCanvas()
        {
            double borderRadius = Math.Min(canvas.Width, canvas.Height) / 2;
            _rotateTransform = new RotateTransform() { Angle = 0, CenterX = borderRadius, CenterY = borderRadius };
            canvas.RenderTransform = _rotateTransform;
            canvas.RegisterName("rotateTransform", _rotateTransform);
            // draw circles to canvas
            DrawCirclesToCanvas();
            // do animation
            _rotateAnimation.From = 0;
            _rotateAnimation.To = 360;
            _rotateAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
            _rotateAnimation.RepeatBehavior = RepeatBehavior.Forever;
            Storyboard.SetTargetName(_rotateAnimation, "rotateTransform");
            Storyboard.SetTargetProperty(_rotateAnimation, new PropertyPath(RotateTransform.AngleProperty));

            _rotatedStory.Children.Add(_rotateAnimation);
            _rotatedStory.Begin(canvas);
        }

        private const int CircleNum = 10;
        private double AngleStep = 30;
        private const double CircleRadius = 3;

        /// <summary>
        /// draw circles to canvas
        /// </summary>
        private void DrawCirclesToCanvas()
        {
            canvas.Children.Clear();
            double borderRadius = Math.Min(canvas.Width, canvas.Height) / 2;

            int circleIndex = 0;
            double angle = 0;
            SolidColorBrush CircleBrush = resourceDictionary["RoundProgressStyle.Color"] as SolidColorBrush;
            while (circleIndex < CircleNum)
            {
                Ellipse circle = new Ellipse()
                {
                    Width = CircleRadius * 2,
                    Height = CircleRadius * 2,
                    Fill = CircleBrush,
                    Opacity = 0.1 * (circleIndex + 1)
                };

                double topMargin = MathUtils.TopMargin(angle, borderRadius, CircleRadius);
                Canvas.SetTop(circle, topMargin);
                double leftMargin = MathUtils.LeftMargin(angle, borderRadius, CircleRadius);
                Canvas.SetLeft(circle, leftMargin);

                canvas.Children.Add(circle);

                circleIndex++;
                angle += AngleStep;
            }
        }
    }
}
